package com.example.fail5.myapplication;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import com.example.fail5.myapplication.entity.DeskDetail;
import com.example.fail5.myapplication.utils.DensityUtils;
import com.example.fail5.myapplication.utils.ScaleUtlis;


import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.TreeSet;

/**
 * @author Administrator
 */
public class PathMap extends View {
    Path mPath;
    private OnViewClick mViewClick;
    /**
     * 点的集合
     */
    private ArrayList<Point> mWhiteArray = new ArrayList<>();
    public Map<Integer, Point> pointMap = new LinkedHashMap<>(2);
    /**
     * 获取线的长度
     */
    int startX1;
    int endX1;
    int startY1;
    int top;
    /**
     * 是添加还是展示
     */
    private boolean isShow = false;
    private boolean isCanAdd = false;
    private ArrayList<DeskDetail> deskDetails = new ArrayList<>();
    Set<Integer> lines = new TreeSet<>(new ScaleUtlis.MyComparator());
    /**
     * 棋盘的宽度和高度
     */
    private int mPanelWidth;
    /**
     * 每一行的高度
     */
    private float mLineHeight;
    /**
     * 设置棋盘为10*10的网格
     */
    private int maxLine = 4;
    /**
     * 画笔
     */
    /**
     * 计时器，计时点击时长
     */
    Timer timer;
    TimerTask timerTask;
    /**
     * 判断是否进行点击
     */
    boolean isCick = true;
    /**
     * 长按超过0.3秒，触发长按事件
     */
    private static final int LONGPRESSTIME = 500;
    /**
     * 记录上次点击的位置，用来进行移动的模糊处理
     */
    int lastX = 0;
    int lastY = 0;
    private Paint mPaint = new Paint();
    private Paint mPaint2 = new Paint();
    private Paint mPaint1 = new Paint();
    private float density;

    /**
     * 白棋子和黑棋子的图片
     */
    public PathMap(Context context) {
        super(context);
    }

    public PathMap(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        //初始化画笔，获取棋子的图片等

        init();
    }

    private void init() {
        mPaint.setColor(0x88000000);
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint2.setStrokeWidth(10);
        mPaint2.setStyle(Paint.Style.STROKE);
        mPaint2.setColor(Color.RED);
        mPaint2.setAntiAlias(true);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthSize = View.MeasureSpec.getSize(widthMeasureSpec);
        int widthMode = View.MeasureSpec.getMode(widthMeasureSpec);
        int heightSize = View.MeasureSpec.getSize(heightMeasureSpec);
        int heightMode = View.MeasureSpec.getMode(heightMeasureSpec);
        //因为要绘制正方形，所以取宽和高的最小值
        int width = Math.min(widthSize, heightSize);
        Log.d("PathMap", "getTop():" + getTop());
        //heightMode
        if (widthMode == MeasureSpec.AT_MOST) {
            width = heightSize;

        } else if (heightMode == View.MeasureSpec.AT_MOST) {
            width = widthSize;
        }

        setMeasuredDimension(width, width);
    }

    /**
     * 当宽高确定后赋值
     */
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);


        mPanelWidth = getHeight();
        //总高度除以行数为每一行的高度
        mLineHeight = h * 1.0f / maxLine;

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //绘制棋盘
        drawBoard(canvas);
        //绘制棋子
        drawPieces(canvas);
        if (mPath != null) {
            canvas.drawPath(mPath, mPaint2);
        }
    }

    /**
     * @param canvas
     */
    private void drawBoard(Canvas canvas) {
        int w = mPanelWidth;
        float lineHeight = mLineHeight;
        lines.clear();
        for (int i = 0; i < maxLine; i++) {
            int startX = (int) (lineHeight / 2);
            int endX = (int) (w - lineHeight / 2);
            int y = (int) ((0.5 + i) * lineHeight);
            Log.d("lattice", "y:" + y);
            startX1 = startX;
            endX1 = endX;
            if (i == 0) {
                startY1 = y;
            }
            Log.d("PathMap", "startX:" + startX);
            Log.d("PathMap", "endX:" + endX);
            Log.d("PathMap", "startY1:" + startY1);
            canvas.drawLine(startX, y, endX, y, mPaint);
//            canvas.drawLine(startX1, startY1, endX1, startY1, mPaint2);
            if (i == 0 || i == maxLine - 1) {
                canvas.drawLine(y, startX, y, endX, mPaint);
            }
            lines.add(y);
        }
        Log.d("lattice", "linesPoint:" + lines);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int x = (int) event.getX();
        int y = (int) event.getY();
        //手指移动的模糊范围，手指移动超出该范围则取消事件处理
        int length = getWidth() / maxLine;
//        final int indexX = y / length;
//        final int indexY = x / length;

        final Point p = new Point(x, y);
        if (event.getAction() == MotionEvent.ACTION_DOWN
                && event.getPointerCount() == 1) {
            //长按计时器
            timer = new Timer();
            timerTask = new TimerTask() {
                @Override
                public void run() {
                    //长按逻辑触发，isClick置为false，手指移开后，不触发点击事件
                    isCick = false;
                    Point point = getValue(p);
                    if (mViewClick != null && point != null) {
                        mViewClick.onLongClickListener(p);
                    }
                }
            };
            isCick = true;
            timer.schedule(timerTask, LONGPRESSTIME, 1000 * 60 * 60 * 24);
        }
        if (event.getAction() == MotionEvent.ACTION_UP
                && event.getPointerCount() == 1) {
            Log.d("lattice5", "y:" + y + "         x:" + x);
            //没有触发长按逻辑，进行点击事件
            if (isCick && mViewClick != null) {
                if (isCanAdd) {
                    getValidPoint(p);
                } else {
                    Log.d("PathMap", "ssssssssssssss");
                    Point point = getValue(p);
//                    mViewClick.onClickRun(point);
                }
            }
            //取消计时
            timerTask.cancel();
            timer.cancel();
        }
        //出现移动，取消点击和长按事件
//        if (event.getAction() == MotionEvent.ACTION_MOVE) {
//            //如果在一定范围内移动，不处理移动事件
//            if (lastX == indexX && lastY == indexY) {
//                return true;
//            }
//            isCick = false;
//            timerTask.cancel();
//            timer.cancel();
//        }
//        invalidate();
        //表明处理了touch事件

        //一旦触发事件，即改变上次触发事件的坐标
//        lastY = x;
//        lastX = indexX;

        return true;
    }

    /**
     * 得到范围的点QAQ
     *
     * @param p
     */
    private Point getValue(Point p) {
        if (lines.size() > 0 || deskDetails.size() > 0) {
            for (DeskDetail deskDetail : deskDetails) {
                if (deskDetail.getXValue() - p.x <= getAnInt() && deskDetail.getXValue() - p.x >= -getAnInt() && deskDetail.getYValue() - p.y <= getAnInt() && deskDetail.getYValue() - p.y >= -getAnInt()) {
                    return new Point(deskDetail.getXValue(), deskDetail.getYValue());
                }
            }
        }
        return null;
    }

    /**
     * 纠正点
     *
     * @param point
     */
    private void getValidPoint(Point point) {
        if (lines.size() > 0) {
            boolean isRange = false;
//            if (mWhiteArray.size() > 0) {
            for (Point point1 : mWhiteArray) {
                if (point.x - point1.x <= getAnInt() && point.x - point1.x >= -getAnInt() && point.y - point1.y <= getAnInt() && point.y - point1.y >= -getAnInt()) {
                    isRange = true;
                }
            }
            for (Integer integer : lines) {
                if (point.y == integer && !isRange) {
                    mWhiteArray.add(new Point(point.x, integer));
                    return;
                } else {
                    int minX = Collections.min(lines);
                    int maxX = Collections.max(lines);
                    if (!isRange && point.y - integer <= getAnInt() && point.y - integer >= -getAnInt()) {
                        getLinePoint(point, integer, minX, maxX);
                        return;
                    }
                }
            }
        }
    }

    private int getAnInt() {
        return 80;
    }

    /**
     * 得到线上的点
     *
     * @param point
     * @param integer
     * @param minX
     * @param maxX
     */
    private void getLinePoint(Point point, Integer integer, int minX, int maxX) {
        savePoint(point, integer, minX, maxX);
    }

    /**
     * 保存点
     *
     * @param point
     * @param integer
     * @param minX
     * @param maxX
     */
    private void savePoint(Point point, Integer integer, int minX, int maxX) {
        Point point1;
        if (point.x < minX) {
            point1 = new Point(minX, integer);
        } else if (point.x > maxX) {
            point1 = new Point(maxX, integer);
        } else {
            point1 = new Point(point.x, integer);
        }

        mWhiteArray.add(point1);
        if (mViewClick != null) {
            mViewClick.onClick(point1, getTheNumberOfRows(point1), getRow());
        }
//        }
    }

    /**
     * 判断是否可以添加点
     *
     * @param point
     * @return
     */
    private boolean isAdd(Point point) {
        boolean isAdd = false;
        if (mWhiteArray.size() > 0) {
            for (Point point1 : mWhiteArray) {
                Log.d("lattice4", "point.x" + point.x +
                        "+point1.x:" + point1.x);
                if (point.y == point1.y) {
                    isAdd = point.x - point1.x > 12 || point.x - point1.x < -12;
                }
            }
        }
        return isAdd;
    }

    /**
     * 得到行坐标
     *
     * @return
     */
    public ArrayList<Integer> getRow() {
        Set<Integer> integers = new TreeSet<>(new ScaleUtlis.MyComparatorReverseOrder());
        integers.addAll(lines);
        ArrayList<Integer> list = new ArrayList<>();
        list.addAll(integers);
        return list;
    }

    /**
     * 从数据里取
     *
     * @param points
     */

    public void refreshPoint(List<DeskDetail> points) {
        isShow = true;
        mWhiteArray.clear();
        deskDetails.clear();
        deskDetails.addAll(points);

//        top = t;
        invalidate();
    }


    public void refreshPoint(Point starPoint, Point endPoint) {
        pointMap.put(0, starPoint);
        pointMap.put(1, endPoint);
        deskDetails.remove(starPoint);
        deskDetails.remove(endPoint);

        invalidate();


    }

    /**
     * 取消添加点
     *
     * @param point
     */
    public void removePoint(Point point) {
        if (mWhiteArray.size() > 0) {
            for (Point point1 : mWhiteArray) {
                if (point1.x == point.x && point.y == point1.y) {
                    mWhiteArray.remove(point);
                    invalidate();
                    break;
                }
            }
        }
    }

    /**
     * 画出的圆与桌台号
     *
     * @param canvas
     */
    private void drawPieces(Canvas canvas) {
        if (!isShow) {
            for (int i = 0, n = mWhiteArray.size(); i < n; i++) {
                Point whitePoint = mWhiteArray.get(i);
                mPaint1.setStyle(Paint.Style.STROKE);
                mPaint1.setColor(getResources().getColor(R.color.color5));
                // 小圆
                canvas.drawCircle(whitePoint.x, whitePoint.y, 10, mPaint1);
                mPaint1.setColor(getResources().getColor(R.color.color5));
                mPaint1.setTextSize(18);
                canvas.drawText("桌台", whitePoint.x - 30, whitePoint.y + 40, mPaint1);
            }
        } else {
            for (int i = 0; i < deskDetails.size(); i++) {
                int x = deskDetails.get(i).getXValue();
                int y = deskDetails.get(i).getYValue();
                Log.d("222", "x:" + x);
                Log.d("222", "y:" + y);
                x = DensityUtils.dip2px(getContext(), x);
                y = DensityUtils.dip2px(getContext(), y);
                Log.d("111", "x:" + x);
                Log.d("111", "y:" + y);
                Point whitePoint = new Point(x, y);
                mPaint1.setColor(getResources().getColor(R.color.color5));
                mPaint1.setStyle(Paint.Style.STROKE);
                // 小圆
                canvas.drawCircle(whitePoint.x, whitePoint.y, 10, mPaint1);
                mPaint1.setColor(Color.RED);
                mPaint1.setColor(getResources().getColor(R.color.color5));
                mPaint1.setTextSize(18);
                canvas.drawText(deskDetails.get(i).getDeskName(), whitePoint.x - 20, whitePoint.y + 40, mPaint1);

            }
            for (Map.Entry<Integer, Point> integerPointEntry : pointMap.entrySet()) {
                Point whitePoint = integerPointEntry.getValue();
                if (integerPointEntry.getKey() == 0) {
                    mPaint1.setColor(integerPointEntry.getKey() == 0 ? getResources().getColor(R.color.color5) : getResources().getColor(R.color.color5));
                }
                mPaint1.setStyle(Paint.Style.FILL);
                canvas.drawCircle(whitePoint.x, whitePoint.y, 10, mPaint1);
                canvas.drawCircle(whitePoint.x, whitePoint.y, 10, mPaint1);


            }


        }


    }

    /**
     * 改变
     *
     * @param isEdit
     */
    public void change(boolean isEdit) {
//        isShow = isEdit;
        isCanAdd = isEdit;
        Log.d("PathMap", "isEdit:" + isEdit);
        mWhiteArray.clear();
        if (deskDetails.size() > 0 && isCanAdd) {
            for (DeskDetail deskDetail : deskDetails) {
                mWhiteArray.add(new Point(deskDetail.getXValue(), deskDetail.getYValue()));
            }
        }
        invalidate();
    }

    public void setOnViewClick(OnViewClick click) {
        this.mViewClick = click;
    }

    /**
     * 得到第几行
     *
     * @param point
     * @return
     */
    public int getTheNumberOfRows(Point point) {
        int j = 0;
        Set<Integer> integers = new TreeSet<>(new ScaleUtlis.MyComparatorReverseOrder());
        integers.addAll(lines);
        if (integers.size() > 0) {
            List<Integer> integerList = new ArrayList<>(integers);
            for (int i1 = 0; i1 < lines.size(); i1++) {
                if (point.y == integerList.get(i1)) {
                    return i1;
                }
            }
        }
        return j;
    }

    public void setDensity(float density) {
        this.density = density;

    }


    public interface OnViewClick {
        /**
         * 传入的点
         *
         * @param point
         * @param row
         * @param integerSet
         */
        void onClick(Point point, int row, ArrayList<Integer> integerSet);


        /**
         * 长按事件
         *
         * @param point
         */
        void onLongClickListener(Point point);

    }


    public int getFristLine() {
        return Collections.max(lines);
    }


    public int getLastLine() {
        return Collections.min(lines);
    }


    /**
     * 将dp转换为px
     * @param value
     * @return
     */
    public int dp2px(float value){
        final  float scale=getContext().getResources().getDisplayMetrics().density;
        return (int)(value*scale+0.5f);
    }


}

